import os


def seek_start():
    """
    文本模式下，SEEK_SET 的 offset只能为非负值，往后移
    """
    fd = open("file1.txt", mode="r+", encoding="utf8")
    # os.SEEK_SET:从开头开始 ，相对于开头偏移6个字节，注意汉字的偏移是3的整数倍
    fd.seek(6, os.SEEK_SET)
    # read 若无参数或参数大于剩余字节数，则读取所有
    #      若有参数且参数小于剩余字节数，则读指定数量的字节
    my_str = fd.read(1)
    print(my_str)
    fd.close()


def seek_end():
    """
    文本模式下，SEEK_END 的 offset只能为0
    """
    fd = open("file1.txt", mode="r+", encoding="utf8")
    # os.SEEK_END:光标移动到文件的尾部
    fd.seek(0, os.SEEK_END)
    my_str = fd.read()
    print(my_str)  # 读不到内容，是空字符串
    fd.close()


def seek_cur():
    """
    文本模式下，SEEK_CUR 的 offset只能为0
    """
    fd = open("file1.txt", mode="r+", encoding="utf8")
    my_str = fd.read(5)
    print(my_str)
    fd.seek(0, os.SEEK_CUR)
    my_str = fd.read()
    print(my_str)
    fd.close()


def seek_cur_b():
    """
    在b模式下，读取到的是字节流，读取图片，音频，视频
    """
    fd = open("file1.txt", mode="rb+")  # b模式不需要以 encoding 模式打开
    fd.seek(5, os.SEEK_CUR)  # pos=5
    fd.seek(-2, os.SEEK_CUR)  # pos=3
    my_str = fd.read(5)
    print(my_str)
    fd.seek(-5, os.SEEK_END)
    my_str = fd.read()
    print(my_str)


def copy_file():
    fd1 = open("photo.png", mode="rb+")
    fd2 = open("photo_copy.png", mode="wb")
    my_str = fd1.read()
    fd2.write(my_str)
    fd1.close()
    fd2.close()


def modify_file():
    """
    加密文件或者改变文件内容使其md5值改变的方法：修改字节流中的部分字节
    执行一次是加密，再执行一次是解密
    """
    fd = open("photo.png", mode="rb+")

    # 读出下标为10的字节，并修改
    fd.seek(10, os.SEEK_SET)
    tmp_str = fd.read(1)
    invert_str = bytes([~tmp_str[0] & 0xFF])  # 按位取反后限制在0-255范围内

    # 将修改后的字节写回文件下标为10的位置
    fd.seek(10, os.SEEK_SET)
    fd.write(invert_str)
    fd.close()


if __name__ == '__main__':
    # seek_start()
    # seek_end()
    # seek_cur()
    # seek_cur_b()
    # copy_file()
    modify_file()
